package us.versus.them.weeds.constraints;

import flash.display.Graphics;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.Lib;

import us.versus.them.weeds.Vertlet;

class Angle implements Constraint {
	var cos:Float;
	var sin:Float;
	var fixed:Vertlet;
	var varied:Vertlet;

	var isRigid:Bool;

	public function new( fixed:Vertlet, varied:Vertlet, angle:Float, ?isRigid:Bool ) {
		this.fixed = fixed;
		this.varied = varied;
		this.cos = Math.cos( angle );
		this.sin = Math.sin( angle );
		if ( null == isRigid ) {
			this.isRigid = false;
		} else {
			this.isRigid = isRigid;
		}
	}

	public function enforce() {
		var distance = Point.distance( fixed.current, varied.current );
		if ( isRigid ) {
			//semi_rigid( distance );
			rigid( distance );
		} else {
			flexible( distance );
		}
	}

	// this can over correct...
	public function rigid( distance:Float ) {
		varied.current.x = distance * this.cos + fixed.current.x;
		varied.current.y = distance * this.sin + fixed.current.y;
	}

	// this can over correct...
	public function semi_rigid( distance:Float ) {
		var x = distance * this.cos + fixed.current.x;
		var y = distance * this.sin + fixed.current.y;
		varied.current.x += 0.5 * ( x - varied.current.x );
		varied.current.y += 0.5 * ( y - varied.current.y );
	}

	// this moves both points
	public function flexible( distance :Float) {
		var x = fixed.current.x;
		var y = fixed.current.y;

		// completely go there
		var ax = x + distance * this.cos;
		var ay = y + distance * this.sin;

		// move 1/2 way there
		varied.current.x += 0.5 * ( ax - varied.current.x );
		varied.current.y += 0.5 * ( ay - varied.current.y );

		// completely back up from there...
		var ax = varied.current.x - distance * this.cos;
		var ay = varied.current.y - distance * this.sin;

		// move 1/2 way there
		fixed.current.x += 0.5 * ( ax - fixed.current.x );
		fixed.current.y += 0.5 * ( ay - fixed.current.y );


	}
}
